
package bus

import chisel3._
import chisel3.util._
import common.Constants._
import javax.xml.transform.OutputKeys

object AXI4Parameters {
  // These are all fixed by the AXI4 standard:
  val lenBits = 8
  val sizeBits = 3
  val burstBits = 2
  val cacheBits = 4
  val protBits = 3
  val qosBits = 4
  val respBits = 2

  // These are not fixed:
  val idBits = 1
  val addrBits = AddrBits
  val dataBits = XLEN
  val userBits = 1

  def CACHE_RALLOCATE = 8.U(cacheBits.W)
  def CACHE_WALLOCATE = 4.U(cacheBits.W)
  def CACHE_MODIFIABLE = 2.U(cacheBits.W)
  def CACHE_BUFFERABLE = 1.U(cacheBits.W)
  def PROT_PRIVILEDGED = 1.U(protBits.W)
  def PROT_INSECURE = 2.U(protBits.W)
  def PROT_INSTRUCTION = 4.U(protBits.W)

  def BURST_FIXED = 0.U(burstBits.W)
  def BURST_INCR = 1.U(burstBits.W)
  def BURST_WRAP = 2.U(burstBits.W)

  def RESP_OKAY = 0.U(respBits.W)
  def RESP_EXOKAY = 1.U(respBits.W)
  def RESP_SLVERR = 2.U(respBits.W)
  def RESP_DECERR = 3.U(respBits.W)
}

class AXI4LiteBundleA extends Bundle {
  val addr  = Output(UInt(AXI4Parameters.addrBits.W))
  //val prot  = Output(UInt(AXI4Parameters.protBits.W))
}

class AXI4LiteBundleW() extends Bundle {
  val strb = Output(UInt((XLEN/8).W))
  val data  = Output(UInt(XLEN.W))
}

class AXI4LiteBundleB extends Bundle {
  val resp = Output(UInt(AXI4Parameters.respBits.W))
}

class AXI4LiteBundleR() extends AXI4LiteBundleB{
  val data  = Output(UInt(XLEN.W))
}


class AXI4Lite extends Bundle {
  val aw = Decoupled(new AXI4LiteBundleA)
  val w  = Decoupled(new AXI4LiteBundleW)
  val b  = Flipped(Decoupled(new AXI4LiteBundleB))
  val ar = Decoupled(new AXI4LiteBundleA)
  val r  = Flipped(Decoupled(new AXI4LiteBundleR))
}

// AXI4-full
// 突发传输宽度信号 AXSIZE 位宽为 3bit，表示为：传输宽度 = 2 ^ AXSIZE
class AXI4BundleA() extends AXI4LiteBundleA {
  val id = Output(UInt(4.W))
  //val ADDR = Output(UInt(AXI4Parameters.addrBits.W))
  val len = Output(UInt(AXI4Parameters.lenBits.W))  // 猝发长度, 协议中的 AxLen 信号从零开始表示，实际的长度值为 AxLen + 1
  val size = Output(UInt(AXI4Parameters.sizeBits.W))  // 每周期传输数据的字节数量
  val burst = Output(UInt(AXI4Parameters.burstBits.W))
  //val lock = Output(Bool())
  //val cache = Output(UInt(AXI4Parameters.cacheBits.W))
  //val PROT = Output(UInt(AXI4Parameters.qosBits.W))
  //val qos = Output(UInt(4.W)) // 用于每个写交易的地址通道上的4位QoS标识符
  //val region = Output(UInt(4.W))
  //val user = Output(UInt(1.W))
}


class AXI4BundleW() extends AXI4LiteBundleW {
  //val data = Output(UInt(XLEN.W))
  //val strb = Output(UInt((XLEN / 8).W))  // 写选通，对于数据总线的每8位有一个写选通
  val last = Output(Bool()) // 写最后一个
}

class AXI4BundleB() extends AXI4LiteBundleB {
  val id = Output(UInt(4.W))
  //val user = Output(UInt(1.W))
}

class AXI4BundleR extends AXI4LiteBundleR {
  val id = Output(UInt(4.W))
  //val data = Output(UInt(XLEN.W))
  val last = Output(Bool()) // 最后一个
  //val user = Output(UInt(1.W))
}

class AXI4 extends AXI4Lite {
  override val aw = Decoupled(new AXI4BundleA())
  override val w = Decoupled(new AXI4BundleW())
  override val b = Flipped(Decoupled(new AXI4BundleB()))
  override val ar = Decoupled(new AXI4BundleA())
  override val r = Flipped(Decoupled(new AXI4BundleR))
}